package org.pupil.socket.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.pupil.common.Cache;
import org.pupil.common.Host;
import org.pupil.common.URL;
import org.pupil.common.constants.Register;
import org.pupil.common.constants.RpcProxy;
import org.pupil.event.RpcListerLoader;
import org.pupil.proxy.IProxy;
import org.pupil.proxy.ProxyFactory;
import org.pupil.register.RegistryFactory;
import org.pupil.register.RegistryService;
import org.pupil.service.HelloService;
import org.pupil.service.IHelloService;
import org.pupil.socket.codec.RpcDecoder;
import org.pupil.socket.codec.RpcEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @Description: 服务发送方
 * @Author: pupil
 * @Date: 2024/07/09 下午 4:00
 */
public class Client {

    private Logger logger = LoggerFactory.getLogger(Client.class);

    private final String host;  // 服务发送方的ip地址或者主机名

    private final Integer port; // 服务发送方的端口号

    private Bootstrap bootstrap;
    private EventLoopGroup eventLoopGroup;

    public Client(String host, Integer port) throws InterruptedException {
        this.host = host;
        this.port = port;
    }

    // 启动服务发送方
    public void run() {
        bootstrap = new Bootstrap();
        eventLoopGroup = new NioEventLoopGroup(4);

        bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                .addLast(new RpcEncoder())
                                .addLast(new RpcDecoder())
                                .addLast(new ClientHandler());
                    }
                });

        Cache.BOOT_STRAP = bootstrap;
    }

    // 连接服务提供方
    public void connectServer() throws Exception {
        // 循环遍历服务
        for (URL url : Cache.SUBSCRIBE_SERVICE_LIST) {
            final RegistryService registryService = RegistryFactory.get(Register.ZOOKEEPER);
            // 服务发现
            final List<URL> urls = registryService.discoveries(url.getServiceName(), url.getVersion());
            if (!urls.isEmpty()) {
                // 获取服务提供方的资源定位器
                for (URL u : urls) {
                    // 与服务提供方建立连接
                    final ChannelFuture connect = bootstrap.connect(u.getIP(), u.getPort());
                    // 本地缓存
                    Cache.CHANNEL_FUTURE_MAP.put(new Host(u.getIP(),u.getPort()),connect);
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        // 初始化服务监听事件执行器
        new RpcListerLoader().init();
        // 创建服务发送方
        final Client client = new Client("127.0.0.1", 8081);
        client.run();
        // 获取注册中心
        final RegistryService registryService = RegistryFactory.get(Register.ZOOKEEPER);
        // 创建服务发送方需要调用的服务的资源定位符
        final URL url = new URL();
        url.setServiceName(IHelloService.class.getName());
        url.setVersion("1.0");
        // 进行服务订阅
        registryService.subscribe(url);
        // 连接服务提供方
        client.connectServer();
        // 获取代理类工厂
        final IProxy iProxy = ProxyFactory.get(RpcProxy.CG_LIB);
        // 获取代理类
        final IHelloService proxy = iProxy.getProxy(IHelloService.class);
        System.out.println(proxy.hello("pupil~"));
        System.out.println("=========");
        System.out.println(proxy.hello("pupil~"));

    }
}
